//: src/com/silvtar/isync/SSIsync.java
/* 
 * Created by 朴晟宁 <piaosn@gmail.com> on 6/5/2013. 
 * Copyright (c) 2013 朴晟宁. All rights reserved.
 * 
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program;
 * 
 * Modify History:
 * Date        Version    Description
 * 6/ 5/2013   0.1        Create The Class
 */
package com.silvtar.isync;

import java.net.Socket;
import java.util.LinkedList;

import com.silvtar.io.StdOut;
import com.silvtar.io.StreamToolkit;
import com.silvtar.net.Message;
import com.silvtar.net.NetPack;
import com.silvtar.net.transporter.FileTransporter;
import com.silvtar.net.transporter.FileTreeTransporter;
import com.silvtar.sync.model.SSAnalyzer;
import com.silvtar.sync.model.SSException;
import com.silvtar.sync.model.SSTree;
import com.silvtar.sync.model.SSTreeNode;

/**
 * 使用内置传输器的同步类
 * @author 朴晟宁/Silvtar
 * @author piaosn@gmail.com
 * @version 0.1
 */
public class SSIsync extends Thread{

    static boolean lock = false;
    static int threadNumber;
    
    int         isyncCommandPort;
    String      ipAddr;
    
    static FileTreeTransporter ftt;
    int commandPort;
    int dataPort;
    
    String localPath;
    String remotePath;
    SSTree localTree;
    SSTree remoteTree;
    
    /**
     * 构造函数，使用这个函数构造对象后，还需要调用configIsync()方法来配置本类
     */
    public SSIsync() {
        
    }
    
    /**
     * 构造函数
     * @param ipAddr 目标IP地址
     * @param isyncCommandPort isync端口
     * @param commandPort 内置传输器命令端口
     * @param dataPort 内置传输器数据端口
     */
    public SSIsync(String ipAddr, int isyncCommandPort, int commandPort, int dataPort) {
        setName("isync");
        configIsync(ipAddr, isyncCommandPort, commandPort, dataPort);
    }
    
    /**
     * 配置函数
     * @param ipAddr 目标IP地址
     * @param isyncCommandPort isync端口
     * @param commandPort 内置传输器命令端口
     * @param dataPort 内置传输器数据端口
     */
    public void configIsync(String ipAddr, int isyncCommandPort, int commandPort, int dataPort) {
        this.isyncCommandPort = isyncCommandPort;
        this.ipAddr = ipAddr;
        this.commandPort = commandPort;
        this.dataPort = dataPort;
        
        ftt = new FileTreeTransporter(ipAddr, commandPort, dataPort);
    }
    
    /**
     * 开始同步。
     * @param localPath 本地文件路径
     * @param remotePath 远程文件路径
     */
    public void startIsync(String localPath, String remotePath) {
        
        this.localPath = localPath;
        this.remotePath = remotePath;
        start();
    }
    
    public void run() {
        setName("isync" + threadNumber++);
        while (lock) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        lock = true;
        
        // 构造本地树
        localTree = new SSTree(localPath);
        
        // 呼叫服务端开始构造远端树
        Socket cmdSocket = NetPack.connect(ipAddr, isyncCommandPort);
        StreamToolkit cmdST = new StreamToolkit(cmdSocket);
        cmdST.writeObject(new Message("start", Message.SYNC, remotePath));
        
        //接受远端树
        Message message = (Message) cmdST.readObject();
        remoteTree = (SSTree) message.getAccessory();
        
        //分析
        SSAnalyzer ssAnalyzer = new SSAnalyzer(localTree, remoteTree);
        ssAnalyzer.analyze();
        
        //开始传输
        //ftt.startTransport(ssAnalyzer, localPath, remotePath);
        ssAnalyzer.print();
        
        lock = false;
    }
}
